package com.company;


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.awt.Point;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

public class GobangServer {
    private static  int PORT = 5000;
    private static Map<String, PrintWriter> clientWriters = new ConcurrentHashMap<>();
    private static ExecutorService clientHandlingExecutor = Executors.newFixedThreadPool(10);
    private static int nextPlayerNumber = 1;

    private static int ROWS = 15; // 假设棋盘行数为15
    private static int COLS = 15; // 假设棋盘列数为15
    private static int[][] board = new int[ROWS][COLS]; // 棋盘数组
    private static Stack<PlayerMove> moveHistory = new Stack<>(); // 落子历史记录
    private static int currentPlayer = 1; // 初始化当前玩家为1，代表第一个连接的玩家

    // 在 GobangServer 类中
    private static List<MoveRecord> moveRecords = new ArrayList<>();
    private static int currentTurn = 0;

    public  void star(String port,int rows,int clos) {

        ROWS=rows;
        COLS=clos;
        board=new int[rows][clos];
        try (ServerSocket serverSocket = new ServerSocket(Integer.parseInt(port))) {
            System.out.println("服务器正在监听端口: " + port);

            while (true) {


                Socket clientSocket = serverSocket.accept();
                String clientKey = getClientKey(clientSocket);
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                synchronized (clientWriters) {
                    clientWriters.put(clientKey, out);
                    System.out.println("新客户端连接: " + clientKey);
                }
                assignRole(clientSocket); // 分配角色
                clientHandlingExecutor.submit(() -> handleClient(clientSocket, clientKey));
            }
        } catch (IOException e) {
            moveRecords.clear();
            currentTurn=0;
            System.out.println("用户断开清除历史记录");
        }
    }

    // 服务器分配角色
    private static void assignRole(Socket clientSocket) throws IOException {
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        String role = nextPlayerNumber == 1 ? "black" : "white";
        out.println("role," + role);
        nextPlayerNumber = nextPlayerNumber == 1 ? 2 : 1;
    }





    private static void handleUndoRequest(String[] parts, String clientKey) {
        // 假设悔棋请求只简单悔2步
        if (!moveRecords.isEmpty()) {

            moveRecords.remove(moveRecords.size() - 1);
            moveRecords.remove(moveRecords.size() - 1);
            moveRecords.remove(moveRecords.size() - 1);
            MoveRecord lastMove = moveRecords.remove(moveRecords.size() - 1);

            // 更新棋盘状态
            board[lastMove.move.x][lastMove.move.y] = 0;
            // 更新回合数
            currentTurn=-2;
            // 广播悔棋信息给所有客户端

            String undoMessage = "undo,"+"'"+convertMoveRecordsToString(moveRecords)+"'";
            broadcastToAllClients(undoMessage);
            // 广播当前玩家的回合给所有客户端
            broadcastCurrentPlayer(lastMove.player);
        }
    }

    private static void broadcastCurrentPlayer(int currentPlayer) {
        // 根据当前玩家的编号，构建一个字符串消息
        String message = "currentPlayer," + currentPlayer;
        // 遍历所有客户端的输出流，并发送当前玩家的信息
        for (PrintWriter writer : clientWriters.values()) {
            writer.println(message);
        }
    }




    // 新增辅助方法：向所有客户端广播消息
    private static void broadcastToAllClients(String message) {
        System.out.println("hello");
        if (clientWriters.isEmpty()) {
            System.out.println("没有客户端连接，无法广播消息。");
        }
        for (PrintWriter writer : clientWriters.values()) {
            System.out.println("已经运行");
            writer.println(message);
        }
    }

    private static String getClientKey(Socket socket) {
        return socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
    }

    private static void handleClient(Socket clientSocket, String clientKey) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {

                String[] parts = inputLine.split(",");
                System.out.println(Arrays.toString(parts));
                if ("undo".equals(parts[0])) {
                    // 处理悔棋请求
                    handleUndoRequest(parts, clientKey);
                } else if ("move".equals(parts[0])) {
                    // 处理落子请求
                    processMove(parts);
                    if (currentPlayer == 1)
                    {
                        currentPlayer=2;
                    }else
                    {
                        currentPlayer=1;
                    }
                    broadcastCurrentPlayer(currentPlayer);
                } else if("isundo".equals(parts[0]))
                {
                    broadcastToAllClients(inputLine);
                } else if("gameOver".equals(parts[0]))
                {

                    broadcastToAllClients(inputLine);


                }
            }
        } catch (IOException e) {
            moveRecords.clear();
            currentTurn=0;
            System.out.println("用户断开清除历史记录");
        }
    }

    private static void processMove(String[] parts) {
        int player = Integer.parseInt(parts[1]);
        int x = Integer.parseInt(parts[2]);
        int y = Integer.parseInt(parts[3]);
        updateBoard(player, x, y);
        String moveMessage = "move," + parts[1] + "," + parts[2] + "," + parts[3];
        broadcastToAllClients(moveMessage);
        // 记录落子
        moveRecords.add(new MoveRecord(player, new Point(x, y), currentTurn++));
        broadcastMoveRecords(); // 广播最新的 moveRecords
    }

    private static void updateBoard(int player, int x, int y) {
        // 更新棋盘状态，假设 0 表示空，1 表示黑棋，2 表示白棋
        if (x >= 0 && x < ROWS && y >= 0 && y < COLS && board[x][y] == 0) {
            board[x][y] = player;
            // 这里应该记录移动到 moveRecords
            moveRecords.add(new MoveRecord(player, new Point(x, y), currentTurn));
            // 更新当前回合数
            currentTurn++;
        }
    }


    private static void broadcastMoveRecords() {
        String moveRecordData = convertMoveRecordsToString(moveRecords);
        broadcastToAllClients("update," + moveRecordData);
    }

    private static String convertMoveRecordsToString(List<MoveRecord> moveRecords) {
        // 将 moveRecords 转换为字符串形式
        StringBuilder sb = new StringBuilder();
        for (MoveRecord record : moveRecords) {
            sb.append(record.player).append(",")
                    .append(record.move.x).append(",")
                    .append(record.move.y).append(",")
                    .append(record.turn).append(";");
        }
        return sb.toString();
    }



}